<?php
namespace app\command;

use app\admin\model\yun\YunPhoneCdkBatch;
use app\admin\model\yun\YunPhoneCdkExchangeRecord;
use app\qsapi\model\yunPhone\YunPhoneCdkCode;
use app\qsapi\model\yunPhone\YunPhoneOrder;
use app\qsapi\model\yunPhone\YunPhoneOrderMachine;
use app\qsapi\model\yunPhone\YunPhoneUserMachine;
use app\qsapi\model\yunPhone\YunPhoneUserRegister;
use app\qsapi\service\YunPhoneService;
use app\qsapi\validate\YunPhoneCreateValidate;
use think\cache\driver\Redis;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\Exception;

class YunPhoneOrderSend extends Command
{

    protected function configure()
    {
        // 指令配置
        $this->setName('YunPhoneOrderSend');
        // 设置参数
        $this->setDescription('云手机订单发货')->setHelp("php think YunPhoneOrderSend");
    }

    protected function execute(Input $input, Output $output)
    {
        $funCheckThread = "YunPhoneOrderSend";
        if (!funCheckThread($funCheckThread)) return;
        $loop = time();
        while (true) {
            if (time() - $loop > mt_rand(3000, 4000)) {
                exit('重新启动时间:' . date('Y-m-d H:i:s'));
            }
            //校验redis
            $redisKey = "YUN_PHONE_ORDER_QUEUE";
            $redis = new Redis(getRedisConfig());
            $redisLength = $redis->lLen($redisKey);
            $i = 0;
            while ($i < $redisLength) {
                $i++;
                $orderNum = $redis->rPop($redisKey);
                write_log('INFO', 'YunPhoneOrderSend.php', "redis订单号：" . $orderNum, 'send_yun_order_info', true);
                if (empty($orderNum)) {
                    break;
                }
                $this->orderYunSend($orderNum);
            }
            usleep(500000);
        }
    }

    /**
     * @Notes:云手机订单发货脚本
     * @Interface orderYunSend
     */
    public function orderYunSend($orderNum)
    {
        $orderFlag = false;
        $orderInfo = YunPhoneOrder::where(['order_num' => $orderNum])->find();
        if (!empty($orderInfo)) {
            $orderFlag = true;
            if ($orderInfo['order_type'] == 1) {
                $orderFlag = $this->cdkAdd(true, $orderInfo);
            } elseif ($orderInfo['order_type'] == 2) {
                $orderFlag = $this->cdkRenewal(true, $orderInfo);
            }
        }
        if ($orderFlag) {
            if (!(new YunPhoneOrder())->where('id', $orderInfo['id'])->update(['status' => 3])) {
                echo "订单编号{$orderInfo['id']}状态更改失败\r\n";
            }
            echo "订单发货编号：{$orderInfo['id']}成功\r\n";
        } else {
            $redis = new Redis(getRedisConfig());
            $redis->lPush('YUN_PHONE_ORDER_QUEUE', $orderNum);
            echo "订单发货编号{$orderInfo['id']}失败\r\n";
        }
    }

    /**
     * Desc : cdk新增
     * User : Steven
     * Date : 2024-05-17 13:13
     */
    protected function cdkAdd($orderFlag, $orderInfo = [])
    {
        Db::startTrans();
        try {
            $cdk = $orderInfo['cdk'] ?? '';
            if (empty($cdk)) {
                throw new Exception("订单编号{$orderInfo['id']}CDK为空\r\n");
            }
            $time = date("Y-m-d H:i:s");
            $cdkInfo = YunPhoneCdkCode::where('cdk', '=', $orderInfo['cdk'])
                ->where([['start_time', '<=', $time], ['end_time', '>=', $time]])
                ->find();
            if (empty($cdkInfo)) {
                throw new Exception("CDK信息{$orderInfo['ckd']}为空\r\n");
            }
            if (empty($cdkInfo['batch_id'])) {
                throw new Exception("CDK批次ID:{$orderInfo['batch_id']}不存在\r\n");
            }
            //兑换时长
            $duration = YunPhoneCdkBatch::where('id', '=', $cdkInfo['batch_id'])->where(['status' => 1, 'mark' => 1])->value('duration') ?? 0;
            if (empty($duration)) {
                throw new Exception("CDK批次时长:{$duration}为空\r\n");
            }
            //当前为CDK新增订单
            $orderMachineNum = YunPhoneOrderMachine::where(['yun_order_id' => $orderInfo['id'], 'send_status' => 3])->find();
            if (empty($orderMachineNum)) {
                $machineModel = new YunPhoneOrderMachine();
                $machine['type'] = 1;
                $machine['duration'] = $duration;  //兑换时长
                $machine['yun_order_id'] = $orderInfo['id'];
                $machine['member_id'] = $orderInfo['member_id'];
                $machine['client_ip'] = $orderInfo['client_ip'];
                $machine['create_time'] = date('Y-m-d H:i:s');
                $id = $machineModel->insertGetId($machine);
                if (!$id) {
                    write_log('INFO', 'BoxYunOrderService.php', 'yunMakeOrder::CDK兑换云手机报错' . $machineModel->getError(), 'BoxYunOrderMachine', true);
                    throw new Exception("订单发货编号{$orderInfo['id']}CDK兑换云挂机新增失败\r\n");
                }
                $params = [
                    'good_code'    => $orderInfo['good_code'],
                    'order_num'    => $orderInfo['order_num'],
                    'good_num'     => $orderInfo['num'],
                    'validEndTime' => date("Y-m-d H:i:s", strtotime("+ {$duration} day")),
                ];
                $yunPhoneInfo = YunPhoneService::createYunPhoneToUser($orderInfo['member_id'], $params);
                write_log('INFO', 'BoxYunNotify.php', "CDK兑换新增设备发货记录：" . json_encode($yunPhoneInfo, true), 'send_user_yun', true);
                $time = date("Y-m-d H:i:s");
                $userDeviceId = $yunPhoneInfo['data'][0]['userDeviceId'] ?? '';
                if ($yunPhoneInfo['code'] == '1') {
                    $data = [
                        'user_device_id' => $userDeviceId,
                        'send_status'    => 1,
                        'send_time'      => $time,
                        'start_time'     => $time,
                        'end_time'       => date('Y-m-d H:i:s', intval($yunPhoneInfo['data'][0]['validEndTime']) / 1000),
                    ];
                    $result = $machineModel->where('id', $id)->update($data);
                    if (!$result) {
                        throw new Exception("订单发货编号{$orderInfo['id']}CDK兑换云挂机新增失败\r\n");
                    }
                    YunPhoneCdkCode::where('cdk', '=', $cdk)->update(['user_device_id' => $userDeviceId]);
                    YunPhoneCdkExchangeRecord::where('cdk', '=', $cdk)->update(['user_device_id' => $userDeviceId]);
                } else {
                    throw new Exception("订单发货编号{$orderInfo['id']}云挂机cdk新增失败\r\n");
                }
            }
            Db::commit();
        } catch (Exception $e) {
            write_log('INFO', 'BoxYunNotify.php', "新增设备发货记录失败：" . $e->getMessage(), 'send_user_yun', true);
            echo $e->getMessage();
            Db::rollback();
        }

        $orderMachineInfo = YunPhoneOrderMachine::where(['yun_order_id' => $orderInfo['id']])->find();
        if ($orderMachineInfo['send_status'] != 1) {
            $orderFlag = false;
        }
        return $orderFlag;
    }

    /**
     * Desc : cdk续费
     * User : Steven
     * Date : 2024-05-17 13:13
     */
    protected function cdkRenewal($orderFlag, $orderInfo = [])
    {
        try {
            $cdk = $orderInfo['cdk'] ?? '';
            if (empty($cdk)) throw new Exception("订单编号{$orderInfo['id']}CDK为空\r\n");
            $time = date("Y-m-d H:i:s");
            $cdkInfo = YunPhoneCdkCode::where('cdk', '=', $orderInfo['cdk'])->where([['start_time', '<=', $time], ['end_time', '>=', $time]])->find();
            if (empty($cdkInfo)) throw new Exception("CDK信息{$orderInfo['ckd']}为空\r\n");
            if (empty($cdkInfo['batch_id'])) throw new Exception("CDK批次ID:{$orderInfo['batch_id']}不存在\r\n");
            //兑换时长
            $duration = YunPhoneCdkBatch::where('id', '=', $cdkInfo['batch_id'])->where(['status' => 1, 'mark' => 1])->value('duration') ?? 0;
            if (empty($duration)) throw new Exception("CDK批次时长:{$duration}为空\r\n");

            $orderMachineInfo = YunPhoneOrderMachine::where(['yun_order_id' => $orderInfo['id'], 'send_status' => 0])->find();
            if (!empty($orderMachineInfo)) {
                //获取当前云手机信息
                $member_id = $orderMachineInfo['member_id'];
                $userDeviceId = $orderMachineInfo['user_device_id'];
                $duration = $orderMachineInfo['duration'];
                $result = YunPhoneService::renewYunPhoneUser($member_id, $userDeviceId, $duration * 24);
                if ($result['code'] == 1 && $result['data']) {
                    $data = [
                        'send_status' => 1,
                        'send_time'   => date("Y-m-d H:i:s"),
                    ];
                    if (!YunPhoneOrderMachine::where('id', $orderMachineInfo['id'])->update($data)) {
                        throw new Exception("订单发货编号{$orderMachineInfo['id']}云手机续费失败\r\n");
                    }

                    YunPhoneCdkCode::where('cdk', '=', $cdk)->update(['user_device_id' => $userDeviceId]);
                    YunPhoneCdkExchangeRecord::where('cdk', '=', $cdk)->update(['user_device_id' => $userDeviceId]);
                }
            }
        } catch (Exception $e) {
            echo $e->getMessage();
        }


        $orderMachineInfo = YunPhoneOrderMachine::where(['yun_order_id' => $orderInfo['id']])->find();
        if ($orderMachineInfo['send_status'] != 1) {
            $orderFlag = false;
        }
        return $orderFlag;
    }

    public static function createYunPhoneToUser(int $member_id = 0, array $input_params = []): array
    {
        $router_url = config('yun_phone.yun_phone_router.user_create_phone');
        $user = YunPhoneUserRegister::field('user_id')->where(['member_id' => $member_id])->find();
        if (empty($user)) {
            $result = (new YunPhoneService)->getYunPhoneUserRegister($member_id);
            $user['user_id'] = $result['data']['userId'];
        }
        $validate = new YunPhoneCreateValidate();
        if (!$validate->check($input_params)) return ['code' => 0, 'msg' => $validate->getError()];
        $params = [
            'freeBuyFlag'   => 1, //0元购标识; -0：下单时不是0元购, 1：下单时是0元购
            'itemCode'      => $input_params['good_code'],  //商品编码
            'orderNo'       => $input_params['order_num'], //订单号',
            'shipmentsNum'  => intval($input_params['good_num']), //出货数量
            'userId'        => $user['user_id'], //用户ID
            'validEndTime'  => $input_params['validEndTime'], //有效时间
            'deviceAliases' => generateCode(8), //设备别名
        ];
        $result = self::packedData($params, $router_url);
        $code = $result['code'] ?? 0;
        if ($code != 1) return ['code' => 0, 'message' => $result['message'] ?? '创建并绑定云机失败,请稍后再试...'];
        $data = $result['data'] ?? [];
        if (empty($data)) return ['code' => 0, 'message' => '创建并绑定云机失败,请稍后再试...'];
        $insertData = [];
        foreach ($data as $k => $v) {
            $insertData[$k]['member_id'] = $member_id;
            $insertData[$k]['user_id'] = $v['userId'];
            $insertData[$k]['item_code'] = $input_params['good_code'];
            $insertData[$k]['user_device_id'] = $v['userDeviceId'];
            $insertData[$k]['valid_start_time'] = date('Y-m-d H:i:s');
            $insertData[$k]['valid_end_time'] = date('Y-m-d H:i:s', intval($v['validEndTime']) / 1000);
            $insertData[$k]['name'] = $params['deviceAliases'];
        }
        (new YunPhoneUserMachine())->insertAll($insertData);
        return $result;
    }

    public static function renewYunPhoneUser(int $member_id = 0, string $userDeviceId = '', int $increaseHour = 0)
    {
        $machine = YunPhoneUserMachine::where(['member_id' => $member_id, 'user_device_id' => $userDeviceId])->find();
        $user = YunPhoneUserRegister::field('user_id')->where(['member_id' => $member_id])->find();
        if (empty($machine)) return ['code' => 0, 'message' => '云机不存在...'];
        $valid_end_time = strtotime($machine['valid_end_time']);
        if ($valid_end_time < time()) return ['code' => 0, 'message' => '云机已过期,无法续费...'];
        $router_url = config('yun_phone.yun_phone_router.user_renew_phone');
        $params = [
            'increaseHour' => $increaseHour,
            'userDeviceId' => $userDeviceId,
            'userId'       => $user['user_id'],
        ];
        $result = self::packedData($params, $router_url);
        write_log('INFO', 'YunPhoneService.php', "续费设备发货记录：" . json_encode($result, true), 'renew_user_yun', true);
        $code = $result['code'] ?? 0;
        if ($code != 1) return ['code' => 0, 'msg' => $result['message'] ?? '续费失败,请稍后再试...'];
        $machine->save(['valid_end_time' => date('Y-m-d H:i:s', $valid_end_time + $increaseHour * 3600)]);
        return $result;
    }

}
